大家好!
今天我們就要正式介紹變數的宣告方式了!
我們進入今天的主題吧!
JavaScript 目前有 3 種宣告方式,就是昨天提到的 var
、const
和 let
。
其中的 const
和 let
就是為了解決舊版 JavaScript 問題而誕生的宣告方式。
事實上,ES6 問世前,宣告變數一直是 var
的工作,當時也不能宣告常數,因此造成許多編寫上的不便:
window
的屬性接下來將會示範宣告方式的差異:
var
var
是基於函式來區分作用域。
var a = 0;
{
var a = 1;
console.log(a); // 1
}
console.log(a); // 1
a = 0
和 a = 1
位於相同作用域,因此 a = 1
會覆蓋 a = 0
的宣告。
var b = 0;
(function () {
var b = 1;
console.log(b); // 1
})();
console.log(b); // 0
b = 0
和 b = 1
位於不同作用域,因為 b = 1
位於函式內。
const
和 let
const
和 let
是基於區塊表示式(大括號)來區分作用域。
let c = 0;
{
let c = 1;
console.log(c); // 1
}
console.log(a); // 0
c = 0
和 c = 1
位於不同作用域,因為 c = 1
位於區塊內。
接下來會將宣告方式應用於迴圈:
var
for (var i = 0; i < 2; i++) {
setTimeout(function () {
console.log(i);
}, 1000);
}
// 2
// 2
怎麼會這樣?不應該是出現 0
和 1
嗎?
其實結果沒有錯,因為上方的迴圈有點像是下方的情況:
{
{
var i = 0;
setTimeout(function () {
console.log(i);
}, 1000);
}
{
var i = 1;
setTimeout(function () {
console.log(i);
}, 1000);
}
{
var i = 2;
/* i < 2 === false */
}
}
當計時器內的函式執行前,i
已經更新到 2
了,又因為 var
宣告的變數只會於函式區分作用域,因此所有區塊的 i
將會一起更新,當然函式呼叫的 i
也只能是 2
了。
let
for (var i = 0; i < 2; i++) {
setTimeout(function () {
console.log(i);
}, 1000);
}
// 0
// 1
這樣就能出現我們期待的結果了!
上方的迴圈有點像是下方的情況:
{
{
let i = 0;
setTimeout(function () {
console.log(i);
}, 1000);
}
{
let i = 1;
setTimeout(function () {
console.log(i);
}, 1000);
}
{
let i = 2;
/* i < 2 === false */
}
}
儘管計時器的函式是在 i
更新到 2
後才執行,但是因為 let
宣告的變數會於區塊表示式區分作用域,因此每個區塊的 i
都不會互相影響,也無法呼叫其他區塊的 i
,當然函式呼叫的 i
就是相同區塊中的 i
了。
如果迴圈有計數器,請記得不能使用 const
!
差不多也到尾聲了。
如果對文章有任何疑問,歡迎於下方提問和建議!
我是 Felix,我們明天再見!